using System;
using System.Collections.Generic;
using System.Reflection;
using QFramework;
using UnityEngine;


public static class DefaultScriptOrder
{
    public const int First = 10000;
    public const int Second = 1000;
    public const int Third = 100;
    public const int Defualt = 0;
    public const int Back1 = -100;
    public const int Back2 = -1000;
    public const int Back3 = -10000;
}


namespace GGameFramework.Runtime
{
    [DefaultExecutionOrder(-1000)] // 确保最先执行
    public static class ComponentEntry
    {
        /// <summary>
        /// 获取所有系统组件
        /// 初始化
        /// </summary>
        private static readonly List<FrameworkComponent> SystemComponents = new List<FrameworkComponent>();

        /// <summary>
        /// 系统组件字典
        /// 查找
        /// </summary>
        private static readonly Dictionary<Type, object> Systems = new Dictionary<Type, object>();

        #region 公共接口

        // /// <summary>
        // /// 初始化系统组件
        // /// 初始化
        // /// </summary>
        // public static void InitializeSystems()
        // {
        //     //顺序注册组件
        //     SystemComponents.Sort((a, b) => a.Priority.CompareTo(b.Priority));
        //
        //     foreach (var system in SystemComponents)
        //     {
        //         InjectDependencies(system); //注入
        //         // system.Initialize(); //初始化
        //         Debug.Log($"[{system.Priority}] Initialized: {system.GetType().Name}");
        //     }
        // }

        /// <summary>
        /// 获取指定系统组件
        /// 获取
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetSystem<T>() where T : FrameworkComponent
        {
            if (Systems.TryGetValue(typeof(T), out var sys))
            {
                return sys as T;
            }
            Debug.LogError($"[{typeof(T).Name}] Not found!");
            return null;
            //return Systems.TryGetValue(typeof(T), out var sys) ? sys as T : null;
        }

        /// <summary>
        /// 注册所有系统组件
        /// 添加
        /// </summary>
        /// <param name="system"></param>
        public static void RegisterComponent(FrameworkComponent system)
        {
            if (SystemComponents == null)
            {
                Debug.LogError("Framework component is invalid.");
                return;
            }

            Type type = system.GetType();

            foreach (var current in SystemComponents)
            {
                if (current.GetType() == type)
                {
                    Debug.LogError($"Framework component type '{type.FullName}' is already exist.");
                    return;
                }
            }
            
            SystemComponents.Add(system);

            if (!Systems.ContainsKey(system.GetType()))
            {
                Systems[type] = system;
                Debug.Log($"[{system.GetType().Name}] Added: {system.GetType().Name}");
            }
            else
            {
                Debug.LogError($"Framework component type '{type.FullName}' is not registered.");
            }
        }

        /// <summary>
        /// 内部组件依赖使用注入
        /// </summary>
        /// <param name="target"></param>
        public static void InjectDependencies(object target)
        {
            var type = target.GetType();

            // 属性注入
            foreach (var prop in type.GetProperties(
                         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (prop.GetCustomAttribute<InjectAttribute>() != null)
                {
                    var dependency = Resolve(prop.PropertyType);
                    if (dependency != null)
                    {
                        prop.SetValue(target, dependency);
                    }
                    else
                    {
                        Debug.LogError(
                            $"{dependency.GetType().Name} Not Found. Please Cheak SystemCompent Init Order!");
                    }
                }
            }

            // 字段注入
            foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (field.GetCustomAttribute<InjectAttribute>() != null)
                {
                    var dependency = Resolve(field.FieldType);
                    if (dependency != null)
                    {
                        field.SetValue(target, dependency);
                    }
                }
            }

            // 方法注入
            foreach (var method in
                     type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (method.GetCustomAttribute<InjectAttribute>() != null)
                {
                    var parameters = method.GetParameters();
                    var args = new object[parameters.Length];
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        args[i] = Resolve(parameters[i].ParameterType);
                    }

                    method.Invoke(target, args);
                }
            }
        }

        #endregion

        #region 私有方法

        private static object Resolve(Type type)
        {
            // 1. 尝试直接匹配类型
            if (Systems.TryGetValue(type, out var system))
            {
                return system;
            }

            // 2. 尝试匹配实现类
            foreach (var kvp in Systems)
            {
                if (type.IsAssignableFrom(kvp.Key))
                {
                    return kvp.Value;
                }
            }

            Debug.LogError($"Dependency not found: {type.Name}");
            return null;
        }

        #endregion

        #region 废弃方案 组件依赖注入

        // /// <summary>
        // /// 检测组件注入
        // /// </summary>
        // /// <param name="behaviour"></param>
        // /// <returns></returns>
        // private static bool HasInjectAttributes(ISceneComponent behaviour)
        // {
        //     var type = behaviour.GetType();
        //     // 检查字段
        //     if (type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
        //         .Any(f => f.GetCustomAttribute<InjectAttribute>() != null))
        //         return true;
        //     // 检查属性
        //     if (type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
        //         .Any(p => p.GetCustomAttribute<InjectAttribute>() != null))
        //         return true;
        //     // 检查方法
        //     if (type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
        //         .Any(m => m.GetCustomAttribute<InjectAttribute>() != null))
        //         return true;
        //     return false;
        // }
        /// <summary>
        /// 注册场景对象(存在[Inject])
        /// </summary>
        /// <param name="behaviour"></param>
        // public static void RegisterForInjection(ISceneComponent behaviour)
        // {
        //     if (behaviour == null) 
        //         return;
        //
        //     if (HasInjectAttributes(behaviour))
        //     {
        //         if (behaviour is IInitializable) return;
        //     
        //         if (systemsInitialized)
        //         {
        //             Debug.Log($"直接注入无需等待系统组件依赖");
        //             // 系统已初始化：立即注入
        //             InjectDependencies(behaviour);
        //         }
        //         else
        //         {
        //             Debug.Log($"{behaviour}加入带注入依赖队列");
        //             // 系统未初始化：加入待处理队列
        //             pendingInjections.Enqueue(behaviour);
        //         }
        //     }
        // }

        #endregion

        //TODO WantDo 实现外部类（场景对象可以透过[inject]方式去注入系统组件）
    }
}